package app;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Timer;

import javax.swing.JComponent;

import com.dinim.matrix.Matrix;
import com.dinim.matrix.twodimensional.Matrix3x3;
import com.dinim.matrix.twodimensional.Vector3;

public class PhytagorasbaumComponent extends JComponent{

	PhytbaumData pd;
	
	Vector3[] nodes = new Vector3[4];
	
	public PhytagorasbaumComponent() {
		
		
		
		double x = 180;
		double y = 200;
		double width = 50;
		double height = 45;
		
		
		
		nodes[0] = new Vector3(x,y+15);
		nodes[1] = new Vector3(x+width,y);
		nodes[2] = new Vector3(x+width,y+height);
		nodes[3] = new Vector3(x,y+height);
		
		pd = new PhytbaumData(nodes);
		
		Timer t = new Timer();
		//t.schedule(new BaumTimer(pd, this), 0, 100);
		
		pd.changeSpitze(x+15, y-26);
		
		addMouseListener(new MouseListener(){

			public void mouseClicked(MouseEvent e) {
				pd.changeSpitze(e.getX(), e.getY());
				repaint();
			}

			public void mouseEntered(MouseEvent arg0) {
			}

			public void mouseExited(MouseEvent arg0) {
			}

			public void mousePressed(MouseEvent arg0) {
			}

			public void mouseReleased(MouseEvent arg0) {
			}
			
		});
		
		addMouseMotionListener(new MouseMotionListener(){

			public void mouseDragged(MouseEvent e) {
				pd.changeSpitze(e.getX(), e.getY());
				repaint();
			}

			public void mouseMoved(MouseEvent arg0) {
				
			}
			
		});
	}
	
	public void paint(Graphics g) {
		
		Graphics2D g2 = (Graphics2D)g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
						    RenderingHints.VALUE_ANTIALIAS_ON);
		
		
		g.fillRect(0, 0, getWidth(), getHeight());

		doBaumAusrufezeichen(nodes, g, 5, Color.green.darker());
	}
	
	private void doBaumAusrufezeichen(Vector3[] nodes, Graphics g, int nr, Color color){
		g.setColor(color);
		drawNodes(nodes, g);
		
		Vector3[] q1 = new Vector3[]{
			new Vector3(nodes[0]),
			new Vector3(nodes[1]),
			new Vector3(nodes[2]),
			new Vector3(nodes[3])
		};
		
		Vector3[] q2 = new Vector3[]{
			new Vector3(nodes[0]),
			new Vector3(nodes[1]),
			new Vector3(nodes[2]),
			new Vector3(nodes[3])
		};

		Matrix matrix = Matrix3x3.generateStandardMatrix();

		double hoehe = q1[3].getY()-q1[0].getY(); 
		double breite = q1[3].getX()-q1[0].getX();
		matrix.multiplyByMatrix(Matrix3x3.generateTranslationMatrixXY(-breite, -hoehe));
		transform(q1, matrix);
		matrix = Matrix3x3.generateStandardMatrix();
		matrix.multiplyByMatrix(Matrix3x3.generateTranslationMatrixXY(-q1[3].getX(), -q1[3].getY()));
		matrix.multiplyByMatrix(Matrix3x3.generateRotationMatrix(pd.getAlpha()));
		matrix.multiplyByMatrix(Matrix3x3.generateScalingMatrixXY(pd.getAlphaRatio(), pd.getAlphaRatio()));
		matrix.multiplyByMatrix(Matrix3x3.generateTranslationMatrixXY(q1[3].getX(), q1[3].getY()));
		
		transform(q1, matrix);
		
		matrix = Matrix3x3.generateStandardMatrix();
		
		hoehe = q2[2].getY()-q2[1].getY();
		breite = q2[2].getX()-q2[1].getX();
		matrix.multiplyByMatrix(Matrix3x3.generateTranslationMatrixXY(-breite, -hoehe));
		transform(q2, matrix);
		matrix = Matrix3x3.generateStandardMatrix();
		matrix.multiplyByMatrix(Matrix3x3.generateTranslationMatrixXY(-q2[2].getX(), -q2[2].getY()));
		matrix.multiplyByMatrix(Matrix3x3.generateRotationMatrix(pd.getBeta()));
		matrix.multiplyByMatrix(Matrix3x3.generateScalingMatrixXY(pd.getBetaRatio(), pd.getBetaRatio()));
		matrix.multiplyByMatrix(Matrix3x3.generateTranslationMatrixXY(q2[2].getX(), q2[2].getY()));
		
		transform(q2, matrix);

		if(nr > 0){
			doBaumAusrufezeichen(q1, g, nr-1, color);
			doBaumAusrufezeichen(q2, g, nr-1, color);
		}
	}
		
	private void transform(Vector3[] nodes, Matrix matrix){
		for (int i = 0; i < nodes.length; i++) {
			nodes[i].multiplyByMatrix(matrix);
		}
	}
	
	
	private void drawNodes(Vector3[] nodes, Graphics g){
		
//		g.drawLine((int)nodes[0].get(Vector3.X, Vector3.ROW), (int)nodes[0].get(Vector3.Y, Vector3.ROW), 
//				   (int)nodes[3].get(Vector3.X, Vector3.ROW), (int)nodes[3].get(Vector3.Y, Vector3.ROW));
//	
//		g.drawLine((int)nodes[1].get(Vector3.X, Vector3.ROW), (int)nodes[1].get(Vector3.Y, Vector3.ROW), 
//				   (int)nodes[2].get(Vector3.X, Vector3.ROW), (int)nodes[2].get(Vector3.Y, Vector3.ROW));
		
		for (int i = 0; i < nodes.length; i++) {
			if(i == nodes.length-1){
				g.drawLine((int)nodes[i].get(Vector3.X, Vector3.FRIST_COLUMN), (int)nodes[i].get(Vector3.Y, Vector3.FRIST_COLUMN), 
						   (int)nodes[0].get(Vector3.X, Vector3.FRIST_COLUMN), (int)nodes[0].get(Vector3.Y, Vector3.FRIST_COLUMN));
			}else{
				g.drawLine((int)nodes[i].get(Vector3.X, Vector3.FRIST_COLUMN), (int)nodes[i].get(Vector3.Y, Vector3.FRIST_COLUMN), 
						   (int)nodes[i+1].get(Vector3.X, Vector3.FRIST_COLUMN), (int)nodes[i+1].get(Vector3.Y, Vector3.FRIST_COLUMN));
			}	
		}
	}
	
}
